package iamutkarshtiwari.github.io.ananas.editimage.fragment;

import iamutkarshtiwari.github.io.ananas.ResourceTable;
import iamutkarshtiwari.github.io.ananas.editimage.EditImageAbility;
import iamutkarshtiwari.github.io.ananas.editimage.ModuleConfig;
import iamutkarshtiwari.github.io.ananas.editimage.view.RotateImageView;
import io.reactivex.Single;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.PageSlider;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.render.Texture;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageInfo;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Size;

public class RotateFragment extends ComponentContainer implements Component.ClickedListener {
    private static final int INDEX = ModuleConfig.INDEX_ROTATE;
    private static final String TAG = RotateFragment.class.getName();

    private static final int RIGHT_ANGLE = 90;

    //    private Component mainView;
    private RotateImageView rotatePanel;
    //    private Dialog loadingDialog;
    private EditImageAbility editImageAbility;
    private PageSlider pageSlider;
    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    /**
     * 构造
     *
     * @param context    Context对象
     * @param pageSlider PageSlider对象
     */
    public RotateFragment(Context context, PageSlider pageSlider) {
        super(context);
        this.pageSlider = pageSlider;
        editImageAbility = (EditImageAbility) context;
        rotatePanel = editImageAbility.rotatePanel;
        initView();
    }


    private void initView() {
        Component component = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_fragment_rotate_layout, null, false);
        addComponent(component);

        setClickListeners();
    }

    /**
     * 显示自定义视图
     */
    public void onShow() {
        editImageAbility.mode = EditImageAbility.MODE_ROTATE;
        editImageAbility.setMainImageVisibility(Component.HIDE);

        rotatePanel.addBit(editImageAbility.getMainBit(), editImageAbility.getBitmapRect());
        rotatePanel.reset();
        rotatePanel.setVisibility(Component.VISIBLE);
    }

    /**
     * 返回主视图
     */
    public void backToMain() {
        editImageAbility.mode = EditImageAbility.MODE_NONE;
        editImageAbility.mainImage.setVisibility(Component.VISIBLE);
        rotatePanel.setVisibility(Component.HIDE);
        pageSlider.setCurrentPage(0, false);
        pageSlider.setVisibility(Component.HIDE);
        onDestroy();
        editImageAbility.saveOrApply(false);
    }

    //    @Override
    public void onDestroy() {
        compositeDisposable.dispose();
//        super.onDestroy();
    }

    private void setClickListeners() {
        findComponentById(ResourceTable.Id_rotate_left).setClickedListener(this);
        findComponentById(ResourceTable.Id_rotate_right).setClickedListener(this);
        findComponentById(ResourceTable.Id_back_to_main).setClickedListener(this);
    }

    @Override
    public void onClick(Component component) {
        int id = component.getId();

        if (id == ResourceTable.Id_back_to_main) {
            backToMain();
        } else if (id == ResourceTable.Id_rotate_left) {
            float updatedAngle = (float) ((double)rotatePanel.getRotateAngle() - RIGHT_ANGLE);
            rotatePanel.rotateImage(updatedAngle);
        } else if (id == ResourceTable.Id_rotate_right) {
            float updatedAngle = (float) ((double)rotatePanel.getRotateAngle() + RIGHT_ANGLE);
            rotatePanel.rotateImage(updatedAngle);
        }
    }

    /**
     * 应用修改
     */
    public void applyRotateImage() {
        if (rotatePanel.getRotateAngle() == 0 || ((double)rotatePanel.getRotateAngle() % 360D) == 0) {
            backToMain();
        } else {
            compositeDisposable.clear();
            Disposable applyRotationDisposable = applyRotation(editImageAbility.getMainBit())
//                    .subscribeOn(Schedulers.computation())
//                    .observeOn(Schedulers.mainThread())
//                    .doOnSubscribe(subscriber -> loadingDialog.show())
//                    .doFinally(() -> loadingDialog.dismiss())
                    .subscribe(processedBitmap -> {
                        if (processedBitmap == null)
                            return;

                        applyAndExit(processedBitmap);
                    }, e -> {
                        // Do nothing on error
                    });

            compositeDisposable.add(applyRotationDisposable);
        }
    }

    private Single<PixelMap> applyRotation(PixelMap sourceBitmap) {
        return Single.fromCallable(() -> {
            RectFloat imageRect = rotatePanel.getImageNewRect();
//        Bitmap resultBitmap = Bitmap.createBitmap((int) imageRect.width(),
//                (int) imageRect.height(), Bitmap.Config.ARGB_4444);
            PixelMap.InitializationOptions opt = new PixelMap.InitializationOptions();
            opt.size = new Size((int) imageRect.getWidth(), (int) imageRect.getHeight());
            opt.pixelFormat = PixelFormat.ARGB_8888;

            PixelMap resultBitmap = PixelMap.create(opt);

            ImageInfo info = sourceBitmap.getImageInfo();

            Canvas canvas = new Canvas(new Texture(resultBitmap));
            int width = info.size.width >> 1;// sourceBitmap.getWidth() >> 1;
            int height = info.size.height >> 1;// sourceBitmap.getHeight() >> 1;

            float centerX = imageRect.getWidth() / 2;
            float centerY = imageRect.getHeight() / 2;

            float left = centerX - width;
            float top = centerY - height;

            RectFloat destinationRect = new RectFloat(left, top,
                    left + info.size.width, top + info.size.height);
            canvas.save();
            canvas.rotate(
                    rotatePanel.getRotateAngle(),
                    imageRect.getWidth() / 2,
                    imageRect.getHeight() / 2
            );

            canvas.drawPixelMapHolderRect(
                    new PixelMapHolder(sourceBitmap),
                    new RectFloat(0, 0, info.size.width, info.size.height),
                    destinationRect, new Paint());
            canvas.restore();
            return resultBitmap;
        });
    }

    private void applyAndExit(PixelMap resultBitmap) {
        editImageAbility.changeMainBitmap(resultBitmap, true);
        backToMain();
    }
}
